package message

import (
	"encoding/binary"
)

type Response struct {
	HeadLength uint32
	BodyLength uint32
	RequestId  uint32
	Version    uint8
	Compresser uint8
	Serializer uint8

	Err []byte

	Data []byte
}

func EncodeResp(resp *Response) []byte {
	resp.CalculateHeadLength()
	resp.CalculateBodyLength()

	bs := make([]byte, resp.HeadLength+resp.BodyLength)
	// 写入 head 长度数值
	binary.BigEndian.PutUint32(bs[:4], resp.HeadLength)
	// 写入 body 长度数值
	binary.BigEndian.PutUint32(bs[4:8], resp.BodyLength)
	// 写入 RequestId 值
	binary.BigEndian.PutUint32(bs[8:12], resp.RequestId)
	// 写入 Version 值
	bs[12] = resp.Version
	// 写入 Compresser 值
	bs[13] = resp.Compresser
	// 写入 Serializer 值
	bs[14] = resp.Serializer

	data := bs[15:]

	if len(resp.Err) > 0 {
		copy(data[:len(resp.Err)], resp.Err)
		data = data[len(resp.Err):]
	}

	// 写入 data
	copy(data, resp.Data)

	return bs
}

func DecodeResp(data []byte) *Response {
	resp := &Response{}
	resp.HeadLength = binary.BigEndian.Uint32(data[:4])
	resp.BodyLength = binary.BigEndian.Uint32(data[4:8])
	resp.RequestId = binary.BigEndian.Uint32(data[8:12])
	resp.Version = uint8(data[12])
	resp.Compresser = uint8(data[13])
	resp.Serializer = uint8(data[14])

	data = data[15:]
	if resp.HeadLength > 15 {
		resp.Err = data[:resp.HeadLength-15]
		data = data[resp.HeadLength-15:]
	}

	if len(data) > 0 {
		resp.Data = data
	}

	return resp
}

func (resp *Response) CalculateHeadLength() {
	length := 15 + len(resp.Err)
	resp.HeadLength = uint32(length)
}
func (resp *Response) CalculateBodyLength() {
	resp.BodyLength = uint32(len(resp.Data))
}
